﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Persistence.IDao;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Context;
using System.Xml.Linq;
using System.IO;

namespace Domain.Repository
{
    public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
    {
        private ISession DDPos_Current_Session;

        internal RepositoryBase()
        {
            DDPos_Current_Session = SessionFactory.OpenSession();
        }

        static RepositoryBase()
        {
        }

        private ISessionFactory _sessionFactory;

        private ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    try
                    {
                        string fileName = "hibernate.cfg.xml";
                        var configuration = new NHibernate.Cfg.Configuration();
                        var sourceAssembly = System.Reflection.Assembly.GetExecutingAssembly();

                        string ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

                        string resourceName = string.Format("{0}.{1}.{2}", sourceAssembly.GetName().Name, "Config", fileName);

                        Stream stream = sourceAssembly.GetManifestResourceStream(resourceName);
                        if (File.Exists(ConfigurationFile))
                        {
                            XElement _element = XElement.Load(ConfigurationFile);
                            var addElement = _element.Element("appSettings").Elements("add").Where(x => x.Attribute("key").Value == "ConnectionString").FirstOrDefault();
                            if (addElement != null)
                            {
                                string value = addElement.Attribute("value").Value;
                                StreamReader sr = new StreamReader(stream);
                                string line = sr.ReadToEnd();
                                XElement eRoot = XElement.Parse(line);
                                XElement e = eRoot.Descendants().Elements().Where(x => x.Attribute("name").Value == "connection.connection_string").FirstOrDefault();
                                if (e != null)
                                {
                                    e.SetValue(value);
                                }
                                eRoot.Save(fileName);
                                configuration.Configure(fileName);
                                _sessionFactory = configuration.BuildSessionFactory();
                            }
                        }
                    }
                    catch
                    {
                    }
                }
                return _sessionFactory;
            }
        }

        public IDao<T> CurrentDao { get; set; }

        public T Get(object id)
        {
            if (null == id) return null;
            return CurrentDao.Get(id);
        }

        public T Load(object id)
        {
            if (null == id) return null;
            return CurrentDao.Load(id);
        }

        public object Save(T entity)
        {
            if (DDPos_Current_Session == null) return null;
            if (null == entity) return null;
            object obj = DDPos_Current_Session.Save(entity);
            DDPos_Current_Session.Flush();
            return obj;
        }
    }
}